namespace EFS.EventLog
{
	public static class Log
	{
		/// <summary>
		/// Application log writter
		/// </summary>
		public static Loggers.ILogger Logger { get; private set; }

		/// <summary>
		/// Default d
		/// </summary>
		private static EFS.Common.ISelfDescriptor defaultSelfDescriptor = null;

		/// <summary>
		/// Static constructor to init local instance
		/// </summary>
		static Log()
		{
			// keep instance
			Logger = Loggers.Logger.Instance;
		}


		/// <summary>
		/// Set default self descriptor
		/// </summary>
		public static EFS.Common.ISelfDescriptor SetSelfDescriptor { set { defaultSelfDescriptor = value; } }

		/// <summary>
		/// Start async logger
		/// </summary>
		public static void StartAsyncLogger(System.Boolean keepFileLogOpen)
		{
			// log
			LogInfo("Starting Async Log ...", null);

			// open file log
			if (keepFileLogOpen)
			{
				// keep file writer open
				EFS.EventLog.Writers.File.Open();
			}

			// start
			Loggers.AsyncLog.Instance.StartWritter();

			// keep 
			Logger = Loggers.AsyncLog.Instance;

			// log
			LogInfo("Async Log started", null);
		}

		/// <summary>
		/// Stop async logger
		/// </summary>
		public static void StopAsyncLogger()
		{
			// log
			LogInfo("Stopping Async Log ...", null);

			// fall back to direct 
			Logger = Loggers.Logger.Instance;

			// start
			Loggers.AsyncLog.Instance.StopWritter();

			// close file log if left open
			if (EFS.EventLog.Writers.File.IsOpen)
			{
				// keep file writer open
				EFS.EventLog.Writers.File.Close();
			}

			// log
			LogInfo("Async Log stopped", null);
		}

		// Add information
		public static void LogInfo(System.String message, EFS.Common.ISelfDescriptor selfDescriptor = null)
		{
			try
			{
				// complete message
				System.String completeMessage = EFS.EventLog.EventDescriptor.Info(message, null == selfDescriptor? defaultSelfDescriptor : selfDescriptor);

				// log
				Logger.Add(completeMessage,
					EFS.EventLog.Config.Log.FileLog.Filter.Info,
					EFS.EventLog.Config.Log.EmailLog.Filter.Info,
					EFS.EventLog.Config.Log.ConsoleLog.Filter.Info);
			}
			catch (System.Exception)
			{ }
		}

		// Add extended information
		public static void LogExtended(System.String message, EFS.Common.ISelfDescriptor selfDescriptor = null)
		{
			try
			{
				// complete message
				System.String completeMessage = EFS.EventLog.EventDescriptor.Extended(message, null == selfDescriptor? defaultSelfDescriptor : selfDescriptor);

				// log
				Logger.Add(completeMessage,
					EFS.EventLog.Config.Log.FileLog.Filter.Extended,
					EFS.EventLog.Config.Log.EmailLog.Filter.Extended,
					EFS.EventLog.Config.Log.ConsoleLog.Filter.Extended);
			}
			catch (System.Exception)
			{ }
		}

		// Add warning
		public static void LogWarning(System.String message, EFS.Common.ISelfDescriptor selfDescriptor = null)
		{
			try
			{
				// complete message
				System.String completeMessage = EFS.EventLog.EventDescriptor.Warn(message, null == selfDescriptor? defaultSelfDescriptor : selfDescriptor);

				// log
				Logger.Add(completeMessage,
					EFS.EventLog.Config.Log.FileLog.Filter.Warn,
					EFS.EventLog.Config.Log.EmailLog.Filter.Warn,
					EFS.EventLog.Config.Log.ConsoleLog.Filter.Warn);
			}
			catch (System.Exception)
			{ }
		}

		// Add error
		public static void LogError(System.String message, EFS.Common.ISelfDescriptor selfDescriptor = null)
		{
			try
			{
				// complete message
				System.String completeMessage = EFS.EventLog.EventDescriptor.Error(message, null == selfDescriptor? defaultSelfDescriptor : selfDescriptor);

				// log
				Logger.Add(completeMessage,
					EFS.EventLog.Config.Log.FileLog.Filter.Err,
					EFS.EventLog.Config.Log.EmailLog.Filter.Err,
					EFS.EventLog.Config.Log.ConsoleLog.Filter.Err);
			}
			catch (System.Exception)
			{ }
		}


		// Add exception
		public static void LogException(System.Exception exception, EFS.Common.ISelfDescriptor selfDescriptor)
		{
			try
			{
				// ignore thread intrerupt
				if (exception is System.Threading.ThreadAbortException)
				{
					return;
				}

				// complete message
				System.String completeMessage = EFS.EventLog.EventDescriptor.Exception(exception, null == selfDescriptor? defaultSelfDescriptor : selfDescriptor);

				// log
				Logger.Add(completeMessage,
					EFS.EventLog.Config.Log.FileLog.Filter.Except,
					EFS.EventLog.Config.Log.EmailLog.Filter.Except,
					EFS.EventLog.Config.Log.ConsoleLog.Filter.Except);
			}
			catch (System.Exception)
			{ }
		}

		// Add exception
		public static void LogException(System.Exception exception)
		{
			try
			{
				// ignore thread intrerupt
				if (exception is System.Threading.ThreadAbortException)
				{
					return;
				}

				// complete message
				System.String completeMessage = EFS.EventLog.EventDescriptor.Exception(exception, null);

				// log
				Logger.Add(completeMessage,
					EFS.EventLog.Config.Log.FileLog.Filter.Except,
					EFS.EventLog.Config.Log.EmailLog.Filter.Except,
					EFS.EventLog.Config.Log.ConsoleLog.Filter.Except);
			}
			catch (System.Exception)
			{ }
		}
	}
}